import datetime
import functools
import json
import logging
import os
import re
import time
from logging.handlers import RotatingFileHandler
from queue import Full, Queue
from time import monotonic

from config import config, EnvConfig, envConfig


# def load_config():
#     global envConf
#     envConf = EnvConfig()

def basic_log_config(logDir, debug=False):
    log_formate_str = '%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(message)s'
    """配置日志系统，使其追加日志到 app.log 文件。"""
    log_format = logging.Formatter(log_formate_str)
    # 文件日志处理器
    logFilename = os.path.join(logDir, time.strftime("%Y_%m_%d", time.localtime()) + '.log')
    file_handler = RotatingFileHandler(logFilename, maxBytes=1000, backupCount=0, encoding='utf-8')
    file_handler.setFormatter(log_format)
    file_handler.setLevel(logging.INFO)
    # file_handler.setLevel(logging.INFO)
    # 控制台日志处理器
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(log_format)
    console_handler.setLevel(logging.INFO)
    # 获取并配置根日志记录器
    root_logger = logging.getLogger()
    if debug:
        root_logger.setLevel(logging.DEBUG)
    else:
        root_logger.setLevel(logging.INFO)
    if not root_logger.hasHandlers():
        root_logger.addHandler(file_handler)
        root_logger.addHandler(console_handler)
    # 防止日志消息被重复处理
    root_logger.propagate = False


def wechat_log_config(logDir, debug=False):
    log_formate_str = '%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(message)s'
    """配置日志系统，使其追加日志到 app.log 文件。"""
    log_format = logging.Formatter(log_formate_str)
    # 文件日志处理器
    logFilename = os.path.join(logDir, time.strftime("%Y_%m_%d", time.localtime()) + '_wx.log')
    file_handler = RotatingFileHandler(logFilename, maxBytes=4000, backupCount=0, encoding='utf-8')
    file_handler.setFormatter(log_format)
    file_handler.setLevel(logging.INFO)
    # 控制台日志处理器
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(log_format)
    console_handler.setLevel(logging.INFO)
    # 获取并配置根日志记录器
    root_logger = logging.getLogger()
    if debug:
        root_logger.setLevel(logging.DEBUG)
    else:
        root_logger.setLevel(logging.INFO)
    if not root_logger.hasHandlers():
        root_logger.addHandler(file_handler)
        root_logger.addHandler(console_handler)
    # 防止日志消息被重复处理
    root_logger.propagate = False
    root_logger.info("WX Logging started")


def get_appdata_dir():
    data_path = config.APP_DATA_DIR
    if not os.path.exists(data_path):
        logging.info("[INIT] data path not exists, create it: {}".format(data_path))
        os.makedirs(data_path)
    return data_path


class Dequeue(Queue):
    def putleft(self, item, block=True, timeout=None):
        with self.not_full:
            if self.maxsize > 0:
                if not block:
                    if self._qsize() >= self.maxsize:
                        raise Full
                elif timeout is None:
                    while self._qsize() >= self.maxsize:
                        self.not_full.wait()
                elif timeout < 0:
                    raise ValueError("'timeout' must be a non-negative number")
                else:
                    endtime = monotonic() + timeout
                    while self._qsize() >= self.maxsize:
                        remaining = endtime - monotonic()
                        if remaining <= 0.0:
                            raise Full
                        self.not_full.wait(remaining)
            self._putleft(item)
            self.unfinished_tasks += 1
            self.not_empty.notify()

    def putleft_nowait(self, item):
        return self.putleft(item, block=False)

    def _putleft(self, item):
        self.queue.appendleft(item)


def remove_markdown_symbol(text: str):
    # 移除markdown格式，目前先移除**
    if not text:
        return text
    return re.sub(r'\*\*(.*?)\*\*', r'\1', text)


def clean_ai_json(text: str):
    """
    需要大量使用AI解析数据为json格式，AI返回的总是带有markdown中的字符
    :param text:
    :return:
    """
    if not text:
        return text
    return text.replace('```json', '').replace('```', '')


def check_prefix(content, prefix_list):
    if not prefix_list:
        return None
    for prefix in prefix_list:
        if content.startswith(prefix):
            return prefix
    return None


def check_contain(content, keyword_list):
    if not keyword_list:
        return None
    for ky in keyword_list:
        if content.find(ky) != -1:
            return True
    return None


def action_logger(action_type):
    def decorator(func):
        @functools.wraps(func)
        async def wrapper(self, *args, **kwargs):
            try:
                self.add_actions(action_type)
            except AttributeError:
                self.chatDBHandler.add_actions(action_type)
            return await func(self, *args, **kwargs)

        return wrapper

    return decorator


def clean_special_char(text: str):
    """
    保留中文或者英文，把昵称里那些乱七八糟的去掉
    :param text:
    :return:
    """
    cleaned_text = re.sub(r'[^a-zA-Z\u4e00-\u9fff]', '', text)
    return cleaned_text


def compose_attachment_name(is_group, actual_user_nickname, from_user_nickname, filename):
    if is_group:
        return os.path.join(get_tmp_dir(), f"{actual_user_nickname}_{filename}")
    return os.path.join(get_tmp_dir(), f"{from_user_nickname}_{filename}")


def over_deadline() -> datetime.timedelta:
    return config.PACKAGE_DEADLINE_TIME - datetime.datetime.now()


def get_tmp_dir():
    dateStr = datetime.datetime.now().strftime(config.DEFAULT_DATE_FORMAT)
    tmp_path = os.path.join(config.TMP_FILE_ROOT_DIR, dateStr)
    if not os.path.exists(tmp_path):
        os.makedirs(tmp_path)
    return tmp_path


def beatify_df_row(row) -> str:
    rText = '-'.join([str(value) for value in row])
    return '[' + rText.replace('nan', '【空值】') + ']'


def concat_file_reply(filename, text) -> str:
    return f"{filename}{envConfig.FILE_MSG_SPLITER}{text}"


def parse_file_reply(text) -> tuple:
    return text.split(envConfig.FILE_MSG_SPLITER)
